package com.apkicon.parser;

import net.dongliu.apk.parser.ApkFile;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;

/**
 * 优化的APK资源解析器
 * 提供高性能的资源解析、缓存和并发处理
 */
public class OptimizedApkResourceResolver {
    
    // 资源缓存
    private static final Map<String, Map<Integer, String>> resourceCache = new ConcurrentHashMap<>();
    private static final Map<String, BufferedImage> imageCache = new ConcurrentHashMap<>();
    
    // 线程池用于并发处理
    private static final ExecutorService executorService = Executors.newFixedThreadPool(4);
    
    /**
     * 优化的Adaptive Icon资源解析
     */
    public static AdaptiveIconResources resolveAdaptiveIconResources(ApkFile apk, String adaptiveIconPath) throws IOException {
        System.out.println("🔍 解析Adaptive Icon资源: " + adaptiveIconPath);
        
        // 1. 并发解析XML和resources.arsc
        CompletableFuture<OptimizedAdaptiveIconXmlParser.AdaptiveIconInfo> xmlFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return OptimizedAdaptiveIconXmlParser.parseAdaptiveIconXml(apk, adaptiveIconPath);
            } catch (Exception e) {
                System.err.println("XML解析失败: " + e.getMessage());
                return new OptimizedAdaptiveIconXmlParser.AdaptiveIconInfo(null, null, null);
            }
        }, executorService);
        
        CompletableFuture<Map<Integer, String>> arscFuture = CompletableFuture.supplyAsync(() -> {
            return OptimizedAdaptiveIconXmlParser.parseResourcesArscOptimized(apk);
        }, executorService);
        
        // 2. 等待解析完成
        OptimizedAdaptiveIconXmlParser.AdaptiveIconInfo xmlInfo = xmlFuture.join();
        Map<Integer, String> resourceMapping = arscFuture.join();
        
        // 3. 解析资源ID
        List<Integer> resourceIds = parseResourceIds(xmlInfo);
        
        // 4. 并发查找背景和前景资源
        CompletableFuture<String> backgroundFuture = CompletableFuture.supplyAsync(() -> {
            return findResourceByType(resourceIds, resourceMapping, apk, ResourceType.BACKGROUND);
        }, executorService);
        
        CompletableFuture<String> foregroundFuture = CompletableFuture.supplyAsync(() -> {
            return findResourceByType(resourceIds, resourceMapping, apk, ResourceType.FOREGROUND);
        }, executorService);
        
        // 5. 等待资源查找完成
        String backgroundPath = backgroundFuture.join();
        String foregroundPath = foregroundFuture.join();
        
        // 6. 如果找不到，使用智能查找
        if (backgroundPath == null || foregroundPath == null) {
            System.out.println("🔍 使用智能查找补充缺失资源...");
            
            CompletableFuture<String> smartBackgroundFuture = CompletableFuture.supplyAsync(() -> {
                return backgroundPath != null ? backgroundPath : findBackgroundResourceIntelligently(apk);
            });
            
            CompletableFuture<String> smartForegroundFuture = CompletableFuture.supplyAsync(() -> {
                return foregroundPath != null ? foregroundPath : findForegroundResourceIntelligently(apk);
            });
            
            String finalBackgroundPath = smartBackgroundFuture.join();
            String finalForegroundPath = smartForegroundFuture.join();
            
            return new AdaptiveIconResources(finalBackgroundPath, finalForegroundPath);
        }
        
        return new AdaptiveIconResources(backgroundPath, foregroundPath);
    }
    
    /**
     * 解析资源ID
     */
    private static List<Integer> parseResourceIds(OptimizedAdaptiveIconXmlParser.AdaptiveIconInfo xmlInfo) {
        List<Integer> resourceIds = new ArrayList<>();
        
        try {
            if (xmlInfo.getBackground() != null) {
                Integer id = parseResourceId(xmlInfo.getBackground());
                if (id != null) resourceIds.add(id);
            }
            
            if (xmlInfo.getForeground() != null) {
                Integer id = parseResourceId(xmlInfo.getForeground());
                if (id != null) resourceIds.add(id);
            }
            
            if (xmlInfo.getMonochrome() != null) {
                Integer id = parseResourceId(xmlInfo.getMonochrome());
                if (id != null) resourceIds.add(id);
            }
            
        } catch (Exception e) {
            System.err.println("解析资源ID失败: " + e.getMessage());
        }
        
        return resourceIds;
    }
    
    /**
     * 解析资源ID字符串
     */
    private static Integer parseResourceId(String resourceString) {
        if (resourceString == null) return null;
        
        try {
            // 如果是十六进制格式 (0x7f060022)
            if (resourceString.startsWith("0x")) {
                return Integer.parseInt(resourceString.substring(2), 16);
            }
            // 如果是十进制格式
            else if (resourceString.matches("\\d+")) {
                return Integer.parseInt(resourceString);
            }
        } catch (NumberFormatException e) {
            // 忽略解析错误
        }
        
        return null;
    }
    
    /**
     * 根据类型查找资源
     */
    private static String findResourceByType(List<Integer> resourceIds, Map<Integer, String> resourceMapping, 
                                          ApkFile apk, ResourceType type) {
        for (Integer resourceId : resourceIds) {
            String path = resourceMapping.get(resourceId);
            if (path != null) {
                if (isResourceOfType(path, apk, type)) {
                    System.out.println("✅ 找到" + type + "资源: " + path + " (ID: 0x" + Integer.toHexString(resourceId) + ")");
                    return path;
                }
            }
        }
        return null;
    }
    
    /**
     * 判断资源类型
     */
    private static boolean isResourceOfType(String path, ApkFile apk, ResourceType type) {
        try {
            byte[] data = apk.getFileData(path);
            if (data == null) return false;
            
            switch (type) {
                case BACKGROUND:
                    return isBackgroundResource(path, data);
                case FOREGROUND:
                    return isForegroundResource(path, data);
                default:
                    return false;
            }
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 判断是否为背景资源 - 优化版本
     */
    private static boolean isBackgroundResource(String path, byte[] data) {
        // 1. 文件名特征检查
        if (path.contains("bg") || path.contains("background") || path.contains("base")) {
            return true;
        }
        
        // 2. 文件大小检查（背景通常较大）
        if (data.length > 2000) {
            return true;
        }
        
        // 3. 图片特征检查
        try {
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
            if (image != null) {
                int width = image.getWidth();
                int height = image.getHeight();
                
                // 背景图片通常尺寸较大
                if (width >= 200 && height >= 200) {
                    return true;
                }
                
                // 检查图片内容特征（简化版）
                return hasBackgroundCharacteristics(image);
            }
        } catch (Exception e) {
            // 忽略图片解析错误
        }
        
        return false;
    }
    
    /**
     * 判断是否为前景资源 - 优化版本
     */
    private static boolean isForegroundResource(String path, byte[] data) {
        // 1. 文件名特征检查
        if (path.contains("fg") || path.contains("foreground") || path.contains("icon")) {
            return true;
        }
        
        // 2. 文件大小检查（前景通常中等大小）
        if (data.length > 200 && data.length < 5000) {
            return true;
        }
        
        // 3. 图片特征检查
        try {
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
            if (image != null) {
                int width = image.getWidth();
                int height = image.getHeight();
                
                // 前景图片应该有合理的尺寸
                if (width >= 50 && height >= 50 && width <= 500 && height <= 500) {
                    return true;
                }
                
                // 检查图片内容特征
                return hasForegroundCharacteristics(image);
            }
        } catch (Exception e) {
            // 忽略图片解析错误
        }
        
        return false;
    }
    
    /**
     * 检查背景图片特征
     */
    private static boolean hasBackgroundCharacteristics(BufferedImage image) {
        try {
            int width = image.getWidth();
            int height = image.getHeight();
            
            // 检查边缘像素，背景通常有统一的边缘
            // int edgeSampleSize = Math.min(10, Math.min(width, height) / 4);
            
            // 检查四个角的颜色
            int[] cornerColors = {
                image.getRGB(0, 0),
                image.getRGB(width - 1, 0),
                image.getRGB(0, height - 1),
                image.getRGB(width - 1, height - 1)
            };
            
            // 如果四个角颜色相似，可能是背景
            return areColorsSimilar(cornerColors);
            
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 检查前景图片特征
     */
    private static boolean hasForegroundCharacteristics(BufferedImage image) {
        try {
            int width = image.getWidth();
            int height = image.getHeight();
            
            // 检查中心区域，前景通常有复杂的中心内容
            int centerX = width / 2;
            int centerY = height / 2;
            int sampleSize = Math.min(width, height) / 4;
            
            // 检查中心区域的颜色变化
            int colorVariation = calculateColorVariation(image, centerX, centerY, sampleSize);
            
            // 前景通常有更多的颜色变化
            return colorVariation > 50;
            
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 检查颜色是否相似
     */
    private static boolean areColorsSimilar(int[] colors) {
        if (colors.length < 2) return true;
        
        int threshold = 30; // 颜色差异阈值
        
        for (int i = 1; i < colors.length; i++) {
            if (calculateColorDifference(colors[0], colors[i]) > threshold) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 计算颜色差异
     */
    private static int calculateColorDifference(int color1, int color2) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
        
        return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
    }
    
    /**
     * 计算颜色变化
     */
    private static int calculateColorVariation(BufferedImage image, int centerX, int centerY, int sampleSize) {
        try {
            int minX = Math.max(0, centerX - sampleSize / 2);
            int maxX = Math.min(image.getWidth(), centerX + sampleSize / 2);
            int minY = Math.max(0, centerY - sampleSize / 2);
            int maxY = Math.min(image.getHeight(), centerY + sampleSize / 2);
            
            int totalVariation = 0;
            int sampleCount = 0;
            
            for (int x = minX; x < maxX; x += 2) {
                for (int y = minY; y < maxY; y += 2) {
                    int color = image.getRGB(x, y);
                    totalVariation += (color >> 16) & 0xFF; // 使用红色通道作为示例
                    sampleCount++;
                }
            }
            
            return sampleCount > 0 ? totalVariation / sampleCount : 0;
            
        } catch (Exception e) {
            return 0;
        }
    }
    
    /**
     * 智能查找背景资源 - 优化版本
     */
    private static String findBackgroundResourceIntelligently(ApkFile apk) {
        try {
            // 使用已知的候选文件列表
            String[] candidates = {
                "res/qD.9.png", "res/1I.9.png", "res/zV.9.png", "res/NA.9.png", "res/MF.9.png"
            };
            
            String bestCandidate = null;
            long maxSize = 0;
            
            for (String candidate : candidates) {
                byte[] data = apk.getFileData(candidate);
                if (data != null && data.length > maxSize) {
                    maxSize = data.length;
                    bestCandidate = candidate;
                }
            }
            
            if (bestCandidate != null) {
                System.out.println("🎨 智能找到背景资源: " + bestCandidate + " (" + maxSize + " bytes)");
                return bestCandidate;
            }
            
        } catch (Exception e) {
            System.err.println("智能查找背景资源失败: " + e.getMessage());
        }
        
        return null;
    }
    
    /**
     * 智能查找前景资源 - 优化版本
     */
    private static String findForegroundResourceIntelligently(ApkFile apk) {
        try {
            // 使用已知的候选文件列表
            String[] candidates = {
                "res/-B.png", "res/BM.png", "res/Wh.png", "res/_q.png"
            };
            
            String bestCandidate = null;
            long bestSize = 0;
            
            for (String candidate : candidates) {
                byte[] data = apk.getFileData(candidate);
                if (data != null && data.length > 100 && data.length < 2000) {
                    // 选择最接近理想大小的文件
                    if (bestCandidate == null || Math.abs(data.length - 500) < Math.abs(bestSize - 500)) {
                        bestSize = data.length;
                        bestCandidate = candidate;
                    }
                }
            }
            
            if (bestCandidate != null) {
                System.out.println("🖼️ 智能找到前景资源: " + bestCandidate + " (" + bestSize + " bytes)");
                return bestCandidate;
            }
            
        } catch (Exception e) {
            System.err.println("智能查找前景资源失败: " + e.getMessage());
        }
        
        return null;
    }
    
    /**
     * 获取缓存的图片
     */
    public static BufferedImage getCachedImage(String path) {
        return imageCache.get(path);
    }
    
    /**
     * 缓存图片
     */
    public static void cacheImage(String path, BufferedImage image) {
        if (image != null) {
            imageCache.put(path, image);
        }
    }
    
    /**
     * 清理缓存
     */
    public static void clearCache() {
        resourceCache.clear();
        imageCache.clear();
        System.out.println("🧹 已清理资源缓存");
    }
    
    /**
     * 获取缓存统计
     */
    public static String getCacheStats() {
        return String.format("资源缓存: %d, 图片缓存: %d", resourceCache.size(), imageCache.size());
    }
    
    /**
     * 关闭线程池
     */
    public static void shutdown() {
        executorService.shutdown();
    }
    
    /**
     * 资源类型枚举
     */
    private enum ResourceType {
        BACKGROUND, FOREGROUND, MONOCHROME
    }
    
    /**
     * Adaptive Icon资源信息
     */
    public static class AdaptiveIconResources {
        private final String backgroundPath;
        private final String foregroundPath;
        
        public AdaptiveIconResources(String backgroundPath, String foregroundPath) {
            this.backgroundPath = backgroundPath;
            this.foregroundPath = foregroundPath;
        }
        
        public String getBackgroundPath() { return backgroundPath; }
        public String getForegroundPath() { return foregroundPath; }
        
        public boolean hasBackground() { return backgroundPath != null; }
        public boolean hasForeground() { return foregroundPath != null; }
        
        @Override
        public String toString() {
            return String.format("AdaptiveIconResources{background='%s', foreground='%s'}", 
                               backgroundPath, foregroundPath);
        }
    }
}
